unit USearchCriteria;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, StdCtrls, Mask, Buttons, ExtCtrls, ComCtrls, DB,
  Dialogs, Menus, UFrameContants;

type
  TSearchCriteria = class(TControl)
  private
    FFieldName: string;
    FFieldDisplay: string;
    FFieldType: TFieldType;
    FPanel: TPanel;
    FLabel: TLabel;
    FMaskEdit: TMaskEdit;
    FButton: TSpeedButton;
    FSQLOperation: SQLOperation;
    FPopUpMenu: TPopupMenu;
    procedure Add(ATitle: String);
    procedure btOperatorClick(Sender: TObject);
    function SQLOperationToSQL: string;
    procedure mniOperation(Sender: TObject);
  public
    property FieldName: string read FFieldName write FFieldName;
    property FieldType: TFieldType read FFieldType write FFieldType;
    property FieldDisplay: string read FFieldDisplay write FFieldDisplay;
    constructor Create(AOwner: TComponent; FieldName: string; FieldType: TFieldType; FieldDisplay: string); reintroduce; overload;
    procedure Clear;
    function PropertyToSQL: string;
    destructor Destroy; override;
  end;

implementation

{ TSearchCriteria }

constructor TSearchCriteria.Create(AOwner: TComponent; FieldName: string; FieldType: TFieldType; FieldDisplay: string);
var
  I: integer;
  mni: TMenuItem;
begin
  inherited Create(AOwner);

  FPanel := TPanel.Create(AOwner);
  FPanel.Parent := TWinControl(AOwner);

  FLabel    := TLabel.Create(Self);
  FMaskEdit := TMaskEdit.Create(Self);
  FButton   := TSpeedButton.Create(Self);

  self.FieldDisplay := FieldDisplay;
  self.FieldType    := FieldType;
  self.FieldName    := FieldName;

  FPopUpMenu := TPopupMenu.Create(Self);
  FPopUpMenu.AutoPopup := False;
  FPopUpMenu.Alignment := paLeft;

  for i := low(SQLDisplayName) to high(SQLDisplayName) do
    if ( ( ( self.FieldType in ftNonTextTypes + ftFixedSizeTypes ) and ( (i = 0) or (i > 3) ) ) or
         ( not ( self.FieldType in ftNonTextTypes + ftFixedSizeTypes ) and ( (i < 4) or (i = 8) ) ) ) then
    begin
       mni := NewItem(SQLDisplayName[i], 0, False, True, mniOperation, 0, '');
       mni.Tag := i;
       FPopUpMenu.Items.Add(mni);
    end;

  Add(FieldDisplay);
end;

procedure TSearchCriteria.Add(ATitle: String);
begin
  with FPanel do
  begin
    Left    := 0;
    Top     := 0;
    Width   := 185;
    Height  := 55;
    Align   := alLeft;
    TabOrder:= 0;
  end;

  with FLabel do
  begin
    Parent  := FPanel;
    Left    := 8;
    Top     := 8;
    Width   := 33;
    Height  := 13;
    Caption := ATitle;
  end;

  with FButton do
  begin
    Parent  := FPanel;
    Left    := 156;
    Top     := 24;
    Width   := 23;
    Height  := 22;
    Anchors := [];
    Caption := '=';
    OnClick := btOperatorClick;
  end;

  with FMaskEdit do
  begin
    Parent  := FPanel;
    Left    := 8;
    Top     := 24;
    Width   := 132;
    Height  := 21;
    TabStop := True;
    Anchors := [akLeft, akTop, akRight];
    BevelEdges := [beTop, beRight, beBottom];
    TabOrder:= 0;
  end;
end;

procedure TSearchCriteria.Clear;
begin
  FMaskEdit.Clear;
end;

procedure TSearchCriteria.btOperatorClick(Sender: TObject);
var
  APoint: TPoint;
begin
  APoint := TSpeedButton(Sender).ClientToScreen(Point(0, TSpeedButton(Sender).ClientHeight));
  FPopUpMenu.Popup(APoint.X, APoint.Y);
end;

function TSearchCriteria.PropertyToSQL: string;
begin
  result := '';
  if Self.FieldType in ftNonTextTypes + ftFixedSizeTypes then
  begin
    if ( FMaskEdit.Text <> '' ) then
      result := Format(SQLOperationToSQL, [FFieldName, FMaskEdit.Text]);
  end
  else
    result := Format(SQLOperationToSQL, [FFieldName, FMaskEdit.Text]);
end;

function TSearchCriteria.SQLOperationToSQL: string;
begin
  case FSQLOperation of
    soEquals     : result := ' %s = %s ';
    soStarting   : result := ' %s starting %s ';
    soEnding     : result := ' %s like ' + QuotedStr('%%%s');
    soContaining : result := ' %s containing %s ';
    soMinor      : result := ' %s < %s  ';
    soMajor      : result := ' %s > %s  ';
    soMinorEqual : result := ' %s <= %s ';
    soMajorEqual : result := ' %s >= %s ';
    soNotEquals  : result := ' %s != %s ';
  end;
end;

procedure TSearchCriteria.mniOperation(Sender: TObject);
begin
  FButton.Caption := SQLDisplayAlias[ TMenuItem(Sender).Tag ] ;
  FSQLOperation   := SQLOperation( TMenuItem(Sender).Tag );

end;

destructor TSearchCriteria.Destroy;
begin
  FreeAndNil(FMaskEdit);
  FreeAndNil(FLabel);
  FreeAndNil(FButton);
  FreeAndNil(FPopUpMenu);

  FreeAndNil(FPanel);
  inherited;
end;

end.
